package br.ufpe.cin.msc.jrsj2.recommender.persistence.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import br.ufpe.cin.msc.jrsj2.recommender.persistence.dao.ProgramDAO;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.domain.Channel;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.domain.Program;

public class JPAProgramDAO implements ProgramDAO {

	private EntityManager emf;

	public JPAProgramDAO(EntityManager emf) {
		this.emf = emf;
	}

	@Override
	public Program create(Program program) {
		try {
			emf.getTransaction().begin();
			emf.persist(program);
			emf.getTransaction().commit();
			return program;
		} catch (Exception ex) {
			if (emf.getTransaction().isActive())
				emf.getTransaction().rollback();
			ex.printStackTrace();
			return null;
		}
	}

	@Override
	public Program findByTitle(String title) {
		try {
			Query query = emf
					.createQuery("SELECT p FROM Program p WHERE p.title = :title");
			query.setParameter("title", title);
			Program program = (Program) query.getSingleResult();

			if (program == null) {
				query = emf
						.createQuery("SELECT p FROM Program p WHERE p.alternativeTitle = :alternativeTitle");
				query.setParameter("alternativeTitle", title);
				program = (Program) query.getSingleResult();
			}

			return program;
		} catch (NoResultException e) {
			System.out.println("Program `" + title + "` wasn't found on local database.");
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Program get(Object id) {
		try {
			return emf.find(Program.class, id);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Program> loadAll() {
		return emf.createQuery("SELECT p FROM Program p").getResultList();
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Program> loadByChannel(Channel channel) {
		return emf
				.createQuery(
						"SELECT p FROM Program p WHERE p.channel = :channel")
				.setParameter("channel", channel).getResultList();
	}

	@Override
	public void removeByTitle(String title) {
		if (title == null)
			return;

		Program program = findByTitle(title);

		if (program == null)
			return;

		try {
			emf.getTransaction().begin();
			emf.remove(program);
			emf.getTransaction().commit();
		} catch (Exception ex) {
			emf.getTransaction().rollback();
		}
	}

}
